package com.ruoyi.wx.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.service.IOssStrategy;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.service.ISysOssService;
import com.ruoyi.wx.entity.PtExpClass;
import com.ruoyi.wx.entity.PtReport;
import com.ruoyi.wx.entity.PtScore;
import com.ruoyi.wx.entity.vo.PtReportVO;
import com.ruoyi.wx.mapper.PtExpClassMapper;
import com.ruoyi.wx.mapper.PtReportMapper;
import com.ruoyi.wx.mapper.PtScoreMapper;
import com.ruoyi.wx.service.IPtReportService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.Collections;
import java.util.Date;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author moxiu
 * @since 2022-03-04
 */
@Service
public class PtReportServiceImpl extends ServiceImpl<PtReportMapper, PtReport> implements IPtReportService {

    @Autowired
    private PtExpClassMapper ptExpClassMapper;

    @Autowired
    private PtScoreMapper ptScoreMapper;

    @Autowired
    private ISysOssService iSysOssService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadReport(MultipartFile file, Long expId) {
        Long userId = SecurityUtils.getUserId();
        Long deptId = SecurityUtils.getDeptId();
        PtExpClass ptExpClass = ptExpClassMapper.selectOne(Wrappers.lambdaQuery(PtExpClass.class)
            .eq(PtExpClass::getClassId, deptId).eq(PtExpClass::getExpId, expId)
        );
        if (ptExpClass == null) {
            throw new ServiceException("当前实验未开启");
        }
        if (System.currentTimeMillis() > ptExpClass.getEndTime().getTime()) {
            throw new ServiceException("当前实验以结束，请联系老师核查");
        }
        PtScore ptScore = ptScoreMapper.selectOne(Wrappers.lambdaQuery(PtScore.class)
            .eq(PtScore::getUserId, userId).eq(PtScore::getExpId, expId)
        );
        if (ptScore == null || ptScore.getScorePreview() == null || ptScore.getScoreDiscipline() == null || ptScore.getScoreOperate() == null) {
            throw new ServiceException("之前任务未完成，提交失败");
        }
        PtReport ptReport = baseMapper.selectOne(Wrappers.lambdaQuery(PtReport.class)
            .eq(PtReport::getExpId, expId).eq(PtReport::getUserId, userId)
        );
        if (ptReport == null) {
            ptReport = new PtReport();
            ptReport.setExpId(expId);
            ptReport.setUserId(userId);
            ptReport.setSubmitTime(new Date());
            ptReport.setSubmitUrl(iSysOssService.upload(file).getUrl());
            baseMapper.insert(ptReport);
        } else {
            SysOss one = iSysOssService.getOne(Wrappers.lambdaQuery(SysOss.class)
                .eq(SysOss::getUrl, ptReport.getSubmitUrl())
                .select(SysOss::getOssId)
            );
            iSysOssService.deleteWithValidByIds(Collections.singletonList(one.getOssId()), false);
            ptReport.setSubmitUrl(iSysOssService.upload(file).getUrl());
            ptReport.setSubmitTime(new Date());
            baseMapper.updateById(ptReport);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int expReportGetScore(PtReportVO ptReportVO) {
        PtReport copy = new PtReport();
        BeanCopyUtils.copyProperties(ptReportVO, copy);
        copy.setUserId(ptReportVO.getUserId());
        copy.setScoreFinal(ptReportVO.getScoreSum() + ptReportVO.getScoreContent() + ptReportVO.getScoreData() + ptReportVO.getScorePrinciple() + ptReportVO.getScorePurpose() + ptReportVO.getScoreTool());
        copy.setExpId(ptReportVO.getExpId());
        int update = baseMapper.update(copy, Wrappers.lambdaUpdate(PtReport.class)
            .eq(PtReport::getExpId, copy.getExpId()).eq(PtReport::getUserId, copy.getUserId())
        );
        if (update == 1) {
            PtScore ptScore = ptScoreMapper.selectOne(Wrappers.lambdaQuery(PtScore.class)
                .eq(PtScore::getExpId, ptReportVO.getExpId()).eq(PtScore::getUserId, ptReportVO.getUserId())
            );
            assert ptScore != null;
            ptScore.setScoreExp(copy.getScoreFinal());
            ptScore.setScoreFinal(ptScore.getScorePreview() * Constants.SCORE_PREVIEW_P
                + ptScore.getScoreOperate() * Constants.SCORE_OPERATE_P
                + ptScore.getScoreDiscipline() * Constants.SCORE_DISCIPLINE_P
                + copy.getScoreFinal()
            );
            return ptScoreMapper.updateById(ptScore);
        }else {
            return 0;
        }
    }
}
